package br.slic.jsf;

import java.io.IOException;
import java.util.ArrayList; 
import java.util.List;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DualListModel;
import org.primefaces.model.UploadedFile;

import br.slic.entidade.Insumo;
import br.slic.entidade.Linha;
import br.slic.entidade.Produto;
import br.slic.exception.ServiceException;
import br.slic.services.interfaces.ArquivoServiceLocal;
import br.slic.services.interfaces.GenericServiceLocal;
import br.slic.util.DadosUtil;
import br.slic.util.SLICConstantes;

@ManagedBean
@ViewScoped
public class ProdutoBean extends CRUD<Produto> {

	private static final long serialVersionUID = 4061330851168447396L;

	@EJB
	private GenericServiceLocal genericService;

	@EJB
	private ArquivoServiceLocal arquivoService;
	
	private static final int TAB_DADOS 		= 0;
	private static final int TAB_IMAGEM 	= 1;

	private boolean exibirImagem;
	
	private int tabSelecionada = TAB_DADOS;

	private List<SelectItem> linhas = new ArrayList<SelectItem>();

	private DualListModel<Insumo> insumos = new DualListModel<Insumo>();

	@Override
	protected List<Produto> getEntidadesImpl() throws ServiceException {
		return genericService.obterEntidades(Produto.class);
	}

	@Override
	protected void editarImpl() throws ServiceException {
		List<Insumo> insumos = genericService.obterListaLazy(getEntidade(), Insumo.class, "produtos");
		getEntidade().setInsumos(insumos);
		carregarPadrao();
	}

	@Override
	protected void novoImpl() throws ServiceException {
		setEntidade(new Produto());
		carregarPadrao();
	}

	@Override
	protected void salvarImpl() throws ServiceException {
		getEntidade().setInsumos(insumos.getTarget());
		super.salvarImpl();
	}
	
	private void carregarPadrao() throws ServiceException {
		carregarInsumos();
		carregarLinhas();
		carregarImagem();
		setTabSelecionada(TAB_DADOS);		
	}
	
	private void carregarInsumos() throws ServiceException {
		List<Insumo> insumos = genericService.obterEntidades(Insumo.class);
		if (!DadosUtil.isEmpty(getEntidade().getId())) {
			insumos.removeAll(getEntidade().getInsumos());
		}
		this.insumos = new DualListModel<Insumo>(insumos, getEntidade().getInsumos());
	}
	
	private void carregarLinhas() throws ServiceException {
		this.linhas = new ArrayList<SelectItem>(); 
		List<Linha> linhas = genericService.obterEntidades(Linha.class);
		for(Linha linha : linhas) {
			this.linhas.add(new SelectItem(linha, linha.getNome()));
		}
	}
	
	public void atualizarImagem(FileUploadEvent event) {
		try {
			UploadedFile arquivo = event.getFile();
			String caminhoImagem = arquivoService.gravarImagem(arquivo.getInputstream(), arquivo.getFileName());
			getEntidade().setCaminhoImagem(caminhoImagem);
			carregarImagem();
		} catch (IOException e) {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
			e.printStackTrace();
		}
		
	}
	
	private void carregarImagem() {
		setExibirImagem(!DadosUtil.isEmpty(getEntidade().getCaminhoImagem()));
		setTabSelecionada(TAB_IMAGEM);
	}
	
	/**
	 * @return the tabSelecionada
	 */
	public int getTabSelecionada() {
		return tabSelecionada;
	}
	
	/**
	 * @param tabSelecionada the tabSelecionada to set
	 */
	public void setTabSelecionada(int tabSelecionada) {
		this.tabSelecionada = tabSelecionada;
	}
	
	/**
	 * @return the linhas
	 */
	public List<SelectItem> getLinhas() {
		return linhas;
	}

	/**
	 * @param linhas the linhas to set
	 */
	public void setLinhas(List<SelectItem> linhas) {
		this.linhas = linhas;
	}

	/**
	 * @return the exibirImagem
	 */
	public boolean isExibirImagem() {
		return exibirImagem;
	}

	/**
	 * @param exibirImagem the exibirImagem to set
	 */
	public void setExibirImagem(boolean exibirImagem) {
		this.exibirImagem = exibirImagem;
	}

	/**
	 * @return the insumos
	 */
	public DualListModel<Insumo> getInsumos() {
		return insumos;
	}

	/**
	 * @param insumos the insumos to set
	 */
	public void setInsumos(DualListModel<Insumo> insumos) {
		this.insumos = insumos;
	}

	@Override
	protected String getNomeFuncionalidade() {
		return SLICConstantes.NOME_FUNCIONALIDADE_PRODUTOS;
	}
}
